<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小画家流程图</title>
    <script src="html2canvas.min.js"></script>
    <script>
        // 添加 CanvasRenderingContext2D.roundRect 方法的兼容性实现
        if (CanvasRenderingContext2D.prototype.roundRect === undefined) {
            CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height, radius) {
                if (width < 2 * radius) radius = width / 2;
                if (height < 2 * radius) radius = height / 2;
                this.beginPath();
                this.moveTo(x + radius, y);
                this.arcTo(x + width, y, x + width, y + height, radius);
                this.arcTo(x + width, y + height, x, y + height, radius);
                this.arcTo(x, y + height, x, y, radius);
                this.arcTo(x, y, x + width, y, radius);
                this.closePath();
                return this;
            };
        }
    </script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Microsoft YaHei', '微软雅黑', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
        }

        header {
            background: rgba(255, 255, 255, 0.95);
            padding: 15px 20px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .logo {
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 24px;
            font-weight: bold;
            color: #764ba2;
        }

        .logo-icon {
            width: 40px;
            height: 40px;
            background: linear-gradient(135deg, #667eea, #764ba2);
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 24px;
        }

        .header-buttons {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s;
            font-weight: 500;
        }

        .btn-primary {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
        }

        .btn-secondary {
            background: white;
            color: #764ba2;
            border: 2px solid #764ba2;
        }

        .btn-secondary:hover {
            background: #f0f0ff;
        }

        .main-container {
            flex: 1;
            display: flex;
            gap: 20px;
            padding: 20px;
            max-width: 1400px;
            width: 100%;
            margin: 0 auto;
        }

        .sidebar {
            width: 250px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
        }

        .sidebar h3 {
            color: #764ba2;
            margin-bottom: 15px;
            font-size: 18px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .shapes-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 10px;
            margin-bottom: 20px;
        }

        .shape-item {
            aspect-ratio: 1;
            background: white;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            cursor: grab;
            transition: all 0.3s;
            padding: 10px;
        }

        .shape-item:hover {
            border-color: #667eea;
            transform: scale(1.05);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
        }

        .shape-item:active {
            cursor: grabbing;
        }

        .shape-icon {
            width: 50px;
            height: 50px;
            margin-bottom: 5px;
            pointer-events: none;
        }

        .shape-name {
            font-size: 12px;
            color: #666;
        }

        .templates-section {
            margin-top: 30px;
        }

        .template-item {
            background: white;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            padding: 10px;
            margin-bottom: 10px;
            cursor: pointer;
            transition: all 0.3s;
        }

        .template-item:hover {
            border-color: #667eea;
            background: #f8f9ff;
        }

        .template-title {
            font-size: 14px;
            color: #333;
            font-weight: 500;
        }

        .template-desc {
            font-size: 12px;
            color: #999;
            margin-top: 5px;
        }

        .canvas-container {
            flex: 1;
            background: white;
            border-radius: 15px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            position: relative;
            overflow: hidden;
        }

        #canvas {
            width: 100%;
            height: 100%;
            position: relative;
            background: 
                linear-gradient(90deg, #f0f0f0 1px, transparent 1px),
                linear-gradient(180deg, #f0f0f0 1px, transparent 1px);
            background-size: 20px 20px;
        }

        .flowchart-element {
            position: absolute;
            cursor: move;
            user-select: none;
            transition: transform 0.1s;
            z-index: 10;
        }

        .flowchart-element:hover {
            transform: scale(1.02);
        }

        .flowchart-element.selected {
            filter: drop-shadow(0 0 8px rgba(102, 126, 234, 0.6));
            z-index: 11;
        }

        .flowchart-element.connecting {
            filter: drop-shadow(0 0 12px rgba(76, 175, 80, 0.8));
            animation: pulse 1s infinite;
        }

        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        .flowchart-element svg {
            pointer-events: none;
        }

        .element-content {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: white;
            padding: 5px;
            text-align: center;
            outline: none;
            background: transparent;
            border: none;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
            font-weight: bold;
            pointer-events: none;
        }

        .element-content.editing {
            pointer-events: auto;
        }

        /* 连线 */
        .connection-line {
            position: absolute;
            pointer-events: all;
            cursor: pointer;
            z-index: 1;
        }
        
        .connection-line:hover {
            stroke: #333;
            stroke-width: 3;
        }
        
        .connection-line.selected {
            stroke: #2196F3;
            stroke-width: 3;
        }
        
        /* 连线文字 */
        .connection-text {
            position: absolute;
            background: white;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 2px 6px;
            font-size: 12px;
            pointer-events: all;
            cursor: text;
            z-index: 2;
            min-width: 20px;
            text-align: center;
        }
        
        .connection-text:hover {
            border-color: #bbb;
        }
        
        .connection-text.editing {
            border-color: #2196F3;
            box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2);
        }
        
        /* 右键菜单 */
        .context-menu {
            position: absolute;
            background: white;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 4px 0;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 1000;
        }
        
        .context-menu-item {
            padding: 8px 16px;
            cursor: pointer;
        }
        
        .context-menu-item:hover {
            background-color: #f0f0f0;
        }
        
        /* 控制点 */
        .control-point, .endpoint-point {
            fill: #2196F3;
            stroke: white;
            stroke-width: 1;
            cursor: move;
        }
        
        .endpoint-point {
            fill: #4CAF50;
        }

        .connection-mode-indicator {
            position: fixed;
            top: 80px;
            left: 50%;
            transform: translateX(-50%);
            background: #4CAF50;
            color: white;
            padding: 10px 20px;
            border-radius: 20px;
            font-size: 14px;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
            z-index: 1000;
            animation: slideDown 0.3s ease-out;
        }

        @keyframes slideDown {
            from {
                transform: translateX(-50%) translateY(-20px);
                opacity: 0;
            }
            to {
                transform: translateX(-50%) translateY(0);
                opacity: 1;
            }
        }

        .help-panel {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: white;
            border-radius: 15px;
            padding: 15px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
            max-width: 300px;
            transform: translateY(120%);
            transition: transform 0.3s;
        }

        .help-panel.show {
            transform: translateY(0);
        }

        .help-toggle {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            border: none;
            cursor: pointer;
            font-size: 24px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
            transition: all 0.3s;
        }

        .help-toggle:hover {
            transform: scale(1.1);
        }

        .color-picker {
            display: flex;
            gap: 8px;
            margin-top: 15px;
            flex-wrap: wrap;
        }

        .color-option {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            cursor: pointer;
            border: 3px solid transparent;
            transition: all 0.3s;
        }

        .color-option:hover {
            transform: scale(1.2);
        }

        .color-option.selected {
            border-color: #333;
        }

        .toast {
            position: fixed;
            top: 100px;
            left: 50%;
            transform: translateX(-50%) translateY(-20px);
            background: white;
            padding: 15px 25px;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
            opacity: 0;
            transition: all 0.3s;
            z-index: 1000;
        }

        .toast.show {
            opacity: 1;
            transform: translateX(-50%) translateY(0);
        }

        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 999;
            align-items: center;
            justify-content: center;
        }

        .modal.show {
            display: flex;
        }

        .modal-content {
            background: white;
            border-radius: 15px;
            padding: 30px;
            max-width: 500px;
            width: 90%;
            animation: slideIn 0.3s;
        }

        @keyframes slideIn {
            from {
                transform: translateY(-50px);
                opacity: 0;
            }
            to {
                transform: translateY(0);
                opacity: 1;
            }
        }

        .modal h2 {
            color: #764ba2;
            margin-bottom: 20px;
        }

        .modal-buttons {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
            margin-top: 20px;
        }

        .confirm-dialog {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            z-index: 1001;
            display: none;
        }

        .confirm-dialog.show {
            display: block;
            animation: slideIn 0.3s;
        }

        .confirm-dialog h3 {
            color: #764ba2;
            margin-bottom: 15px;
        }

        .confirm-dialog p {
            color: #666;
            margin-bottom: 20px;
        }

        .confirm-buttons {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
        }

        @media (max-width: 768px) {
            .main-container {
                flex-direction: column;
            }
            
            .sidebar {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <header>
        <div class="logo">
            <div class="logo-icon">🎨</div>
            <span>小画家流程图</span>
        </div>
        <div class="header-buttons">
            <button class="btn btn-secondary" id="clearBtn">🗑️ 清空画布</button>
            <button class="btn btn-primary" onclick="exportImage()">📸 导出图片</button>
        </div>
    </header>

    <main class="main-container">
        <aside class="sidebar">
            <h3>🔷 基本图形</h3>
            <div class="shapes-grid">
                <div class="shape-item" draggable="true" data-shape="start">
                    <svg class="shape-icon" viewBox="0 0 100 100">
                        <ellipse cx="50" cy="50" rx="45" ry="25" fill="#4CAF50" stroke="#333" stroke-width="2"/>
                    </svg>
                    <span class="shape-name">开始</span>
                </div>
                <div class="shape-item" draggable="true" data-shape="process">
                    <svg class="shape-icon" viewBox="0 0 100 100">
                        <rect x="10" y="25" width="80" height="50" fill="#2196F3" stroke="#333" stroke-width="2" rx="5"/>
                    </svg>
                    <span class="shape-name">处理</span>
                </div>
                <div class="shape-item" draggable="true" data-shape="decision">
                    <svg class="shape-icon" viewBox="0 0 100 100">
                        <path d="M50 10 L90 50 L50 90 L10 50 Z" fill="#FF9800" stroke="#333" stroke-width="2"/>
                    </svg>
                    <span class="shape-name">判断</span>
                </div>
                <div class="shape-item" draggable="true" data-shape="end">
                    <svg class="shape-icon" viewBox="0 0 100 100">
                        <ellipse cx="50" cy="50" rx="45" ry="25" fill="#F44336" stroke="#333" stroke-width="2"/>
                    </svg>
                    <span class="shape-name">结束</span>
                </div>
                <div class="shape-item" draggable="true" data-shape="parallelogram">
                    <svg class="shape-icon" viewBox="0 0 100 100">
                        <path d="M20 25 L80 25 L70 75 L10 75 Z" fill="#9C27B0" stroke="#333" stroke-width="2"/>
                    </svg>
                    <span class="shape-name">输入/输出</span>
                </div>
            </div>

            <h3>🎨 颜色选择</h3>
            <div class="color-picker">
                <div class="color-option selected" style="background: #4CAF50" data-color="#4CAF50"></div>
                <div class="color-option" style="background: #2196F3" data-color="#2196F3"></div>
                <div class="color-option" style="background: #FF9800" data-color="#FF9800"></div>
                <div class="color-option" style="background: #F44336" data-color="#F44336"></div>
                <div class="color-option" style="background: #9C27B0" data-color="#9C27B0"></div>
                <div class="color-option" style="background: #00BCD4" data-color="#00BCD4"></div>
                <div class="color-option" style="background: #FFC107" data-color="#FFC107"></div>
                <div class="color-option" style="background: #795548" data-color="#795548"></div>
            </div>

            <div class="templates-section">
                <h3>📖 使用说明</h3>
                <div class="template-item">
                    <div class="template-title">1. 添加图形</div>
                    <div class="template-desc">从左侧拖拽图形到画布上</div>
                </div>
                <div class="template-item">
                    <div class="template-title">2. 编辑文字</div>
                    <div class="template-desc">双击图形或连线文字进行编辑</div>
                </div>
                <div class="template-item">
                    <div class="template-title">3. 创建连接</div>
                    <div class="template-desc">点击一个图形后，再点击需要连接的另一个图形即可完成连线，如果取消则点击空白处</div>
                </div>
                <div class="template-item">
                    <div class="template-title">4. 删除连接</div>
                    <div class="template-desc">单击连线，按Delete键可以进行删除</div>
                </div>
            </div>
        </aside>

        <section class="canvas-container">
            <div id="canvas"></div>
        </section>
    </main>

    <button class="help-toggle" onclick="toggleHelp()">?</button>
    <div class="help-panel" id="helpPanel">
        <h3>💡 使用帮助</h3>
        <p style="margin-top: 10px; font-size: 14px; color: #666;">
            1. 从左侧拖拽图形到画布<br>
            2. 双击图形可以编辑文字<br>
            3. 连线方式：<br>
            &nbsp;&nbsp;• 按住Ctrl键点击两个图形<br>
            &nbsp;&nbsp;• 或直接点击第一个图形，再点击第二个<br>
            4. 单击选中连线，按Delete键删除<br>
            5. 双击连线在中间位置添加文字<br>
            6. 点击颜色可以改变图形颜色
        </p>
    </div>

    <div id="toast" class="toast"></div>

    <!-- 导出模态框 -->
    <div id="exportModal" class="modal">
        <div class="modal-content">
            <h2>📤 正在导出</h2>
            <p>图片生成中，请稍候...</p>
            <canvas id="exportCanvas" style="display: none;"></canvas>
            <div class="modal-buttons">
                <button class="btn btn-secondary" onclick="closeModal()">取消</button>
                <button class="btn btn-primary" onclick="downloadImage()" id="downloadBtn" style="display: none;">下载图片</button>
            </div>
        </div>
    </div>

    <!-- 确认对话框 -->
    <div id="confirmDialog" class="confirm-dialog">
        <h3>⚠️ 确认清空</h3>
        <p>确定要清空画布上的所有内容吗？此操作无法撤销。</p>
        <div class="confirm-buttons">
            <button class="btn btn-secondary" onclick="cancelClear()">取消</button>
            <button class="btn btn-primary" onclick="confirmClear()">确定清空</button>
        </div>
    </div>

    <script>
        let selectedElement = null;
        let selectedConnection = null;
        let selectedColor = '#4CAF50';
        let elements = [];
        let connections = [];
        let elementIdCounter = 0;
        let isConnecting = false;
        let firstElement = null;
        let connectingElement = null;
        let connectionModeIndicator = null;

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            initDragAndDrop();
            initColorPicker();
            initKeyboardShortcuts();
            initClearButton();
            initCanvasClick();
            loadFromLocal();
        });

        // 初始化画布点击事件
        function initCanvasClick() {
            const canvas = document.getElementById('canvas');
            canvas.addEventListener('click', (e) => {
                if (e.target === canvas) {
                    // 点击空白区域，取消连线模式
                    if (connectingElement) {
                        cancelConnectionMode();
                    }
                }
            });
        }

        // 初始化清空按钮
        function initClearButton() {
            const clearBtn = document.getElementById('clearBtn');
            clearBtn.addEventListener('click', function() {
                showConfirmDialog();
            });
        }

        // 显示确认对话框
        function showConfirmDialog() {
            const confirmDialog = document.getElementById('confirmDialog');
            if (confirmDialog) {
                confirmDialog.classList.add('show');
            }
        }

        // 取消清空
        function cancelClear() {
            const confirmDialog = document.getElementById('confirmDialog');
            if (confirmDialog) {
                confirmDialog.classList.remove('show');
            }
        }

        // 确认清空
        function confirmClear() {
            const confirmDialog = document.getElementById('confirmDialog');
            if (confirmDialog) {
                confirmDialog.classList.remove('show');
            }
            
            // 清空画布
            const canvas = document.getElementById('canvas');
            if (canvas) {
                canvas.innerHTML = '';
            }
            
            // 重置所有数据
            elements = [];
            connections = [];
            elementIdCounter = 0;
            selectedElement = null;
            selectedConnection = null;
            isConnecting = false;
            firstElement = null;
            connectingElement = null;
            
            showToast('🧹 画布已清空');
        }

        // 拖拽功能
        function initDragAndDrop() {
            const shapes = document.querySelectorAll('.shape-item');
            const canvas = document.getElementById('canvas');

            shapes.forEach(shape => {
                shape.addEventListener('dragstart', (e) => {
                    e.dataTransfer.effectAllowed = 'copy';
                    e.dataTransfer.setData('shape', shape.dataset.shape);
                });
            });

            canvas.addEventListener('dragover', (e) => {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'copy';
            });

            canvas.addEventListener('drop', (e) => {
                e.preventDefault();
                const shapeType = e.dataTransfer.getData('shape');
                if (shapeType) {
                    const rect = canvas.getBoundingClientRect();
                    const x = e.clientX - rect.left - 60;
                    const y = e.clientY - rect.top - 30;
                    createShape(shapeType, x, y);
                }
            });
        }

        // 创建图形
        function createShape(type, x, y) {
            const element = document.createElement('div');
            element.className = 'flowchart-element';
            element.id = `element-${elementIdCounter++}`;
            element.style.left = x + 'px';
            element.style.top = y + 'px';
            // 设置初始尺寸，后续会根据内容调整
            element.style.width = '120px';
            element.style.height = '60px';
            element.dataset.type = type;
            element.dataset.color = selectedColor;

            let svgContent = '';
            let defaultText = '';

            switch(type) {
                case 'start':
                    svgContent = `<svg width="120" height="60" viewBox="0 0 120 60">
                        <ellipse cx="60" cy="30" rx="55" ry="25" fill="${selectedColor}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    defaultText = '开始';
                    break;
                case 'process':
                    svgContent = `<svg width="120" height="60" viewBox="0 0 120 60">
                        <rect x="10" y="10" width="100" height="40" fill="${selectedColor}" stroke="#333" stroke-width="2" rx="5"/>
                    </svg>`;
                    defaultText = '处理步骤';
                    break;
                case 'decision':
                    svgContent = `<svg width="120" height="60" viewBox="0 0 120 60">
                        <path d="M60 5 L115 30 L60 55 L5 30 Z" fill="${selectedColor}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    defaultText = '判断';
                    break;
                case 'end':
                    svgContent = `<svg width="120" height="60" viewBox="0 0 120 60">
                        <ellipse cx="60" cy="30" rx="55" ry="25" fill="${selectedColor}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    defaultText = '结束';
                    break;
                case 'parallelogram':
                    svgContent = `<svg width="120" height="60" viewBox="0 0 120 60">
                        <path d="M20 10 L100 10 L80 50 L0 50 Z" fill="${selectedColor}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    defaultText = '输入/输出';
                    break;
            }

            element.innerHTML = svgContent;

            // 添加文字内容
            const textContent = document.createElement('div');
            textContent.className = 'element-content';
            textContent.textContent = defaultText;
            element.appendChild(textContent);

            // 添加事件监听
            element.addEventListener('mousedown', startDrag);
            element.addEventListener('click', selectElement);
            element.addEventListener('dblclick', (e) => {
                e.stopPropagation();
                const content = element.querySelector('.element-content');
                content.contentEditable = true;
                content.classList.add('editing');
                content.focus();
                selectAllText(content);
                
                // 编辑完成后移除编辑状态并调整大小
                const finishEditing = () => {
                    content.contentEditable = false;
                    content.classList.remove('editing');
                    adjustElementSize(element); // 调整图形大小以适应文字
                    updateConnections(); // 更新连接线
                };
                
                content.addEventListener('blur', finishEditing, { once: true });
                content.addEventListener('keydown', (e) => {
                    if (e.key === 'Enter') {
                        e.preventDefault();
                        content.blur();
                    }
                });
            });

            document.getElementById('canvas').appendChild(element);
            elements.push(element);
            
            // 初始调整图形大小以适应默认文字
            setTimeout(() => {
                adjustElementSize(element);
            }, 0);
            
            showToast('✨ 新图形已添加！');
        }

        // 拖动图形
        function startDrag(e) {
            // 防止拖动文字内容
            if (e.target.classList.contains('element-content')) return;
            
            e.preventDefault();
            const element = e.currentTarget;
            const startX = e.clientX - element.offsetLeft;
            const startY = e.clientY - element.offsetTop;

            function drag(e) {
                const canvas = document.getElementById('canvas');
                const canvasRect = canvas.getBoundingClientRect();
                
                // 获取元素当前尺寸
                const elementWidth = parseFloat(element.style.width);
                const elementHeight = parseFloat(element.style.height);
                
                let newX = e.clientX - startX;
                let newY = e.clientY - startY;
                
                // 限制在画布内
                newX = Math.max(0, Math.min(newX, canvasRect.width - elementWidth));
                newY = Math.max(0, Math.min(newY, canvasRect.height - elementHeight));
                
                element.style.left = newX + 'px';
                element.style.top = newY + 'px';
                updateConnections();
            }

            function stopDrag() {
                document.removeEventListener('mousemove', drag);
                document.removeEventListener('mouseup', stopDrag);
            }

            document.addEventListener('mousemove', drag);
            document.addEventListener('mouseup', stopDrag);
        }

        // 根据文字内容调整图形大小
        function adjustElementSize(element) {
            const textContent = element.querySelector('.element-content');
            if (!textContent) return;
            
            // 创建一个临时的测量元素
            const measureElement = document.createElement('div');
            measureElement.style.position = 'absolute';
            measureElement.style.visibility = 'hidden';
            measureElement.style.whiteSpace = 'nowrap';
            measureElement.style.font = 'bold 14px Microsoft YaHei';
            measureElement.style.padding = '10px';
            measureElement.style.boxSizing = 'border-box';
            measureElement.textContent = textContent.textContent || ' ';
            document.body.appendChild(measureElement);
            
            // 测量文字尺寸
            let width = measureElement.offsetWidth;
            let height = measureElement.offsetHeight;
            
            // 移除测量元素
            document.body.removeChild(measureElement);
            
            // 确保最小尺寸
            width = Math.max(width, 80);
            height = Math.max(height, 40);
            
            // 添加一些内边距
            width += 20;
            height += 20;
            
            // 更新元素尺寸
            element.style.width = width + 'px';
            element.style.height = height + 'px';
            
            // 重新创建SVG以适应新尺寸
            const type = element.dataset.type;
            const color = element.dataset.color || '#2196F3';
            let svgContent = '';
            
            switch(type) {
                case 'start':
                case 'end':
                    // 椭圆形
                    svgContent = `<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
                        <ellipse cx="${width/2}" cy="${height/2}" rx="${width/2 - 5}" ry="${height/2 - 5}" fill="${color}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    break;
                case 'process':
                    // 矩形
                    svgContent = `<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
                        <rect x="5" y="5" width="${width - 10}" height="${height - 10}" fill="${color}" stroke="#333" stroke-width="2" rx="5"/>
                    </svg>`;
                    break;
                case 'decision':
                    // 菱形
                    svgContent = `<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
                        <path d="M${width/2} 5 L${width - 5} ${height/2} L${width/2} ${height - 5} L5 ${height/2} Z" fill="${color}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    break;
                case 'parallelogram':
                    // 平行四边形
                    const offset = Math.min(width / 3, 30);
                    svgContent = `<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
                        <path d="M${offset} 5 L${width - 5} 5 L${width - offset - 5} ${height - 5} L5 ${height - 5} Z" fill="${color}" stroke="#333" stroke-width="2"/>
                    </svg>`;
                    break;
            }
            
            element.innerHTML = svgContent;
            element.appendChild(textContent);
        }

        // 导出图片
        function exportImage() {
            const canvas = document.getElementById('canvas');
            const exportCanvas = document.getElementById('exportCanvas');
            
            // 显示模态框和加载提示
            document.getElementById('exportModal').classList.add('show');
            
            // 获取模态框中的提示文本元素
            const modalText = document.querySelector('#exportModal .modal-content p');
            
            // 更新提示文本为导出中状态
            modalText.textContent = '图片生成中，请稍候...';
            
            // 隐藏下载按钮，显示加载提示
            document.getElementById('downloadBtn').style.display = 'none';
            
            // 获取画布的实际尺寸和滚动信息
            const rect = canvas.getBoundingClientRect();
            const scrollLeft = canvas.scrollLeft;
            const scrollTop = canvas.scrollTop;
            const canvasWidth = canvas.scrollWidth;
            const canvasHeight = canvas.scrollHeight;
            
            // 设置导出画布尺寸
            exportCanvas.width = canvasWidth;
            exportCanvas.height = canvasHeight;
            
            const ctx = exportCanvas.getContext('2d');
            ctx.fillStyle = '#ffffff';
            ctx.fillRect(0, 0, exportCanvas.width, exportCanvas.height);
            ctx.fillStyle = '#333';
            ctx.font = '16px Microsoft YaHei';
            ctx.textAlign = 'center';
            ctx.fillText('正在生成图片...', exportCanvas.width / 2, exportCanvas.height / 2);
            
            // 创建离屏画布
            const offscreenCanvas = document.createElement('canvas');
            offscreenCanvas.width = canvasWidth;
            offscreenCanvas.height = canvasHeight;
            const offscreenCtx = offscreenCanvas.getContext('2d');
            
            // 清空离屏画布
            offscreenCtx.fillStyle = '#ffffff';
            offscreenCtx.fillRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
            
            // 绘制背景网格
            offscreenCtx.fillStyle = '#f0f0f0';
            for (let x = 0; x < offscreenCanvas.width; x += 20) {
                offscreenCtx.fillRect(x, 0, 1, offscreenCanvas.height);
            }
            for (let y = 0; y < offscreenCanvas.height; y += 20) {
                offscreenCtx.fillRect(0, y, offscreenCanvas.width, 1);
            }
            
            // 延时确保所有元素加载完成
            setTimeout(() => {
                try {
                    // 绘制所有流程图元素
                    const flowchartElements = document.querySelectorAll('.flowchart-element');
                    flowchartElements.forEach(element => {
                        // 获取元素相对于画布的位置
                        const elementRect = element.getBoundingClientRect();
                        const canvasRect = canvas.getBoundingClientRect();
                        const left = elementRect.left - canvasRect.left + scrollLeft;
                        const top = elementRect.top - canvasRect.top + scrollTop;
                        const width = elementRect.width;
                        const height = elementRect.height;
                        const type = element.dataset.type;
                        const color = element.dataset.color || '#2196F3';
                        
                        // 绘制元素
                        offscreenCtx.fillStyle = color;
                        offscreenCtx.strokeStyle = '#333';
                        offscreenCtx.lineWidth = 2;
                        
                        switch (type) {
                            case 'start':
                            case 'end':
                                // 绘制椭圆
                                offscreenCtx.beginPath();
                                offscreenCtx.ellipse(left + width/2, top + height/2, width/2 - 5, height/2 - 5, 0, 0, Math.PI * 2);
                                offscreenCtx.fill();
                                offscreenCtx.stroke();
                                break;
                            case 'process':
                                // 绘制矩形
                                offscreenCtx.beginPath();
                                offscreenCtx.roundRect(left + 5, top + 5, width - 10, height - 10, 5);
                                offscreenCtx.fill();
                                offscreenCtx.stroke();
                                break;
                            case 'decision':
                                // 绘制菱形
                                offscreenCtx.beginPath();
                                offscreenCtx.moveTo(left + width/2, top + 5);
                                offscreenCtx.lineTo(left + width - 5, top + height/2);
                                offscreenCtx.lineTo(left + width/2, top + height - 5);
                                offscreenCtx.lineTo(left + 5, top + height/2);
                                offscreenCtx.closePath();
                                offscreenCtx.fill();
                                offscreenCtx.stroke();
                                break;
                            case 'parallelogram':
                                // 绘制平行四边形
                                const offset = Math.min(width / 3, 30);
                                offscreenCtx.beginPath();
                                offscreenCtx.moveTo(left + offset, top + 5);
                                offscreenCtx.lineTo(left + width - 5, top + 5);
                                offscreenCtx.lineTo(left + width - offset - 5, top + height - 5);
                                offscreenCtx.lineTo(left + 5, top + height - 5);
                                offscreenCtx.closePath();
                                offscreenCtx.fill();
                                offscreenCtx.stroke();
                                break;
                        }
                        
                        // 绘制元素文本
                        const textElement = element.querySelector('.element-content');
                        if (textElement && textElement.textContent) {
                            offscreenCtx.fillStyle = 'white';
                            offscreenCtx.font = 'bold 14px Microsoft YaHei';
                            offscreenCtx.textAlign = 'center';
                            offscreenCtx.textBaseline = 'middle';
                            offscreenCtx.fillText(textElement.textContent, left + width/2, top + height/2);
                        }
                    });
                    
                    // 绘制连接线
                    connections.forEach(conn => {
                        if (!conn.element1 || !conn.element2) return;
                        
                        // 获取画布位置信息
                        const canvasRect = canvas.getBoundingClientRect();
                        
                        // 计算元素中心点
                        const rect1 = conn.element1.getBoundingClientRect();
                        const rect2 = conn.element2.getBoundingClientRect();
                        const centerX1 = rect1.left + rect1.width / 2 - canvasRect.left + scrollLeft;
                        const centerY1 = rect1.top + rect1.height / 2 - canvasRect.top + scrollTop;
                        const centerX2 = rect2.left + rect2.width / 2 - canvasRect.left + scrollLeft;
                        const centerY2 = rect2.top + rect2.height / 2 - canvasRect.top + scrollTop;
                        
                        // 计算边缘连接点 (与画布上一致的算法)
                        const startPoint = getEdgePointForExport(conn.element1, centerX2, centerY2, canvasRect);
                        const endPoint = getEdgePointForExport(conn.element2, centerX1, centerY1, canvasRect);
                        
                        // 绘制连接线
                        offscreenCtx.beginPath();
                        offscreenCtx.moveTo(startPoint.x, startPoint.y);
                        offscreenCtx.lineTo(endPoint.x, endPoint.y);
                        offscreenCtx.strokeStyle = '#666';
                        offscreenCtx.lineWidth = 2;
                        offscreenCtx.stroke();
                        
                        // 绘制箭头
                        const angle = Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x);
                        offscreenCtx.beginPath();
                        offscreenCtx.moveTo(endPoint.x, endPoint.y);
                        offscreenCtx.lineTo(
                            endPoint.x - 10 * Math.cos(angle - Math.PI/6),
                            endPoint.y - 10 * Math.sin(angle - Math.PI/6)
                        );
                        offscreenCtx.lineTo(
                            endPoint.x - 10 * Math.cos(angle + Math.PI/6),
                            endPoint.y - 10 * Math.sin(angle + Math.PI/6)
                        );
                        offscreenCtx.closePath();
                        offscreenCtx.fillStyle = '#666';
                        offscreenCtx.fill();
                    });
                    
                    // 绘制连接线文字
                    connections.forEach(conn => {
                        if (conn.textElement && conn.textElement.textContent) {
                            // 获取文字元素相对于画布的位置
                            const textRect = conn.textElement.getBoundingClientRect();
                            const canvasRect = canvas.getBoundingClientRect();
                            const left = textRect.left - canvasRect.left + scrollLeft;
                            const top = textRect.top - canvasRect.top + scrollTop;
                            
                            // 测量文字尺寸
                            offscreenCtx.font = '12px Microsoft YaHei';
                            const textWidth = offscreenCtx.measureText(conn.textElement.textContent).width;
                            const textHeight = 12; // 近似高度
                            
                            // 绘制文字背景
                            offscreenCtx.fillStyle = 'white';
                            offscreenCtx.fillRect(left - textWidth/2 - 4, top - textHeight/2 - 2, textWidth + 8, textHeight + 4);
                            
                            // 绘制边框
                            offscreenCtx.strokeStyle = '#ddd';
                            offscreenCtx.lineWidth = 1;
                            offscreenCtx.strokeRect(left - textWidth/2 - 4, top - textHeight/2 - 2, textWidth + 8, textHeight + 4);
                            
                            // 绘制文字
                            offscreenCtx.fillStyle = '#333';
                            offscreenCtx.font = '12px Microsoft YaHei';
                            offscreenCtx.textAlign = 'center';
                            offscreenCtx.textBaseline = 'middle';
                            offscreenCtx.fillText(conn.textElement.textContent, left, top);
                        }
                    });
                    
                    // 将离屏画布内容绘制到导出画布上
                    ctx.drawImage(offscreenCanvas, 0, 0);
                    
                    // 更新提示文本为完成状态
                    modalText.textContent = '图片生成完成！';
                    
                    // 显示下载按钮
                    document.getElementById('downloadBtn').style.display = 'inline-block';
                } catch (error) {
                    console.error('导出图片失败:', error);
                    showToast('❌ 导出失败，请重试');
                    closeModal();
                }
            }, 500);
        }

        // 计算图形边缘的连接点 (用于导出)
        function getEdgePointForExport(element, targetX, targetY, canvasRect) {
            const rect = element.getBoundingClientRect();
            
            const centerX = rect.left + rect.width / 2 - canvasRect.left;
            const centerY = rect.top + rect.height / 2 - canvasRect.top;
            const type = element.dataset.type;
            
            // 计算方向向量
            const dx = targetX - centerX;
            const dy = targetY - centerY;
            
            let edgeX, edgeY;
            
            switch(type) {
                case 'start':
                case 'end':
                    // 椭圆形
                    const rx = rect.width / 2 - 5; // 减去边距
                    const ry = rect.height / 2 - 5;
                    const t = Math.atan2(dy * rx, dx * ry);
                    edgeX = centerX + rx * Math.cos(t);
                    edgeY = centerY + ry * Math.sin(t);
                    break;
                    
                case 'process':
                    // 矩形
                    const halfWidth = rect.width / 2 - 5;
                    const halfHeight = rect.height / 2 - 5;
                    
                    // 计算矩形边上的交点
                    if (Math.abs(dx / halfWidth) > Math.abs(dy / halfHeight)) {
                        edgeX = centerX + (dx > 0 ? halfWidth : -halfWidth);
                        edgeY = centerY + dy * halfWidth / Math.abs(dx);
                    } else {
                        edgeX = centerX + dx * halfHeight / Math.abs(dy);
                        edgeY = centerY + (dy > 0 ? halfHeight : -halfHeight);
                    }
                    break;
                    
                case 'decision':
                    // 菱形 - 使用更精确的几何计算
                    const diamondWidth = rect.width / 2 - 5;
                    const diamondHeight = rect.height / 2 - 5;
                    
                    // 处理零向量情况
                    if (dx === 0 && dy === 0) {
                        edgeX = centerX;
                        edgeY = centerY;
                        break;
                    }
                    
                    // 菱形的四个顶点
                    const topPoint = { x: centerX, y: centerY - diamondHeight };
                    const rightPoint = { x: centerX + diamondWidth, y: centerY };
                    const bottomPoint = { x: centerX, y: centerY + diamondHeight };
                    const leftPoint = { x: centerX - diamondWidth, y: centerY };
                    
                    // 计算方向与四个边的交点
                    let minDistance = Infinity;
                    let closestPoint = { x: centerX, y: centerY };
                    
                    // 检查与上边的交点
                    const topIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        topPoint.x, topPoint.y, rightPoint.x, rightPoint.y
                    );
                    if (topIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(topIntersection.x - centerX, 2) + 
                            Math.pow(topIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = topIntersection;
                        }
                    }
                    
                    // 检查与右边的交点
                    const rightIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        rightPoint.x, rightPoint.y, bottomPoint.x, bottomPoint.y
                    );
                    if (rightIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(rightIntersection.x - centerX, 2) + 
                            Math.pow(rightIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = rightIntersection;
                        }
                    }
                    
                    // 检查与下边的交点
                    const bottomIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        bottomPoint.x, bottomPoint.y, leftPoint.x, leftPoint.y
                    );
                    if (bottomIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(bottomIntersection.x - centerX, 2) + 
                            Math.pow(bottomIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = bottomIntersection;
                        }
                    }
                    
                    // 检查与左边的交点
                    const leftIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        leftPoint.x, leftPoint.y, topPoint.x, topPoint.y
                    );
                    if (leftIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(leftIntersection.x - centerX, 2) + 
                            Math.pow(leftIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = leftIntersection;
                        }
                    }
                    
                    edgeX = closestPoint.x;
                    edgeY = closestPoint.y;
                    break;
            }
            
            return { x: edgeX, y: edgeY };
        }

        // 计算两条线段的交点
        function getLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4) {
            const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
            if (Math.abs(denom) < 0.0001) return null; // 平行或重合
            
            const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
            const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom;
            
            if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
                return {
                    x: x1 + t * (x2 - x1),
                    y: y1 + t * (y2 - y1)
                };
            }
            
            return null;
        }

        // 显示提示
        function showToast(message) {
            const toast = document.getElementById('toast');
            toast.textContent = message;
            toast.classList.add('show');
            setTimeout(() => {
                toast.classList.remove('show');
            }, 3000);
        }

        // 关闭模态框
        function closeModal() {
            document.getElementById('exportModal').classList.remove('show');
        }

        // 下载图片
        function downloadImage() {
            const exportCanvas = document.getElementById('exportCanvas');
            const dataURL = exportCanvas.toDataURL('image/png');
            const link = document.createElement('a');
            link.href = dataURL;
            link.download = 'flowchart.png';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            closeModal();
        }

        // 初始化
        function init() {
            document.getElementById('addElement').addEventListener('click', addElement);
            document.getElementById('exportBtn').addEventListener('click', exportImage);
            document.getElementById('downloadBtn').addEventListener('click', downloadImage);
            document.getElementById('exportModal').addEventListener('click', closeModal);
            document.getElementById('canvas').addEventListener('click', startDrag);
        }

        // 选择元素
        function selectElement(e) {
            e.stopPropagation();
            
            // 如果正在连线模式（简单点击方式）
            if (connectingElement) {
                if (e.currentTarget !== connectingElement) {
                    // 完成连线
                    createConnection(connectingElement, e.currentTarget);
                    exitConnectionMode();
                }
                return;
            }
            
            // 清除所有选中状态
            clearSelection();
            
            if (e.ctrlKey) {
                // Ctrl+点击方式 - 传统连线模式
                if (!isConnecting) {
                    isConnecting = true;
                    firstElement = e.currentTarget;
                    firstElement.classList.add('selected');
                    showToast('🔗 点击第二个图形完成连线');
                } else {
                    if (firstElement !== e.currentTarget) {
                        createConnection(firstElement, e.currentTarget);
                    }
                    firstElement.classList.remove('selected');
                    isConnecting = false;
                    firstElement = null;
                }
            } else {
                // 简单点击方式 - 进入连线模式
                enterConnectionMode(e.currentTarget);
            }
        }

        // 进入连线模式（简单点击方式）
        function enterConnectionMode(element) {
            connectingElement = element;
            element.classList.add('connecting');
            
            // 显示连线模式指示器
            showConnectionModeIndicator();
            
            // 清除其他选中状态
            elements.forEach(el => {
                if (el !== element) {
                    el.classList.remove('selected');
                }
            });
            
            element.classList.add('selected');
            selectedElement = element;
        }

        // 退出连线模式
        function exitConnectionMode() {
            if (connectingElement) {
                connectingElement.classList.remove('connecting');
                connectingElement = null;
            }
            hideConnectionModeIndicator();
        }

        // 取消连线模式
        function cancelConnectionMode() {
            exitConnectionMode();
            clearSelection();
            showToast('❌ 已取消连线');
        }

        // 显示连线模式指示器
        function showConnectionModeIndicator() {
            if (connectionModeIndicator) {
                connectionModeIndicator.remove();
            }
            
            connectionModeIndicator = document.createElement('div');
            connectionModeIndicator.className = 'connection-mode-indicator';
            connectionModeIndicator.textContent = '🔗 点击另一个图形完成连线，或点击空白处取消';
            document.body.appendChild(connectionModeIndicator);
        }

        // 隐藏连线模式指示器
        function hideConnectionModeIndicator() {
            if (connectionModeIndicator) {
                connectionModeIndicator.remove();
                connectionModeIndicator = null;
            }
        }

        // 清除所有选中状态
        function clearSelection() {
            document.querySelectorAll('.flowchart-element').forEach(el => {
                el.classList.remove('selected');
                el.classList.remove('connecting');
            });
            document.querySelectorAll('.connection-line').forEach(line => {
                line.classList.remove('selected');
            });
            selectedElement = null;
            selectedConnection = null;
        }

        // 计算图形边缘的连接点
        function getEdgePoint(element, targetX, targetY) {
            const rect = element.getBoundingClientRect();
            const canvasRect = document.getElementById('canvas').getBoundingClientRect();
            
            const centerX = rect.left + rect.width / 2 - canvasRect.left;
            const centerY = rect.top + rect.height / 2 - canvasRect.top;
            const type = element.dataset.type;
            
            // 计算方向向量
            const dx = targetX - centerX;
            const dy = targetY - centerY;
            
            let edgeX, edgeY;
            
            switch(type) {
                case 'start':
                case 'end':
                    // 椭圆形
                    const rx = rect.width / 2 - 5; // 减去边距
                    const ry = rect.height / 2 - 5;
                    const t = Math.atan2(dy * rx, dx * ry);
                    edgeX = centerX + rx * Math.cos(t);
                    edgeY = centerY + ry * Math.sin(t);
                    break;
                    
                case 'process':
                    // 矩形
                    const halfWidth = rect.width / 2 - 5;
                    const halfHeight = rect.height / 2 - 5;
                    
                    // 计算矩形边上的交点
                    if (Math.abs(dx / halfWidth) > Math.abs(dy / halfHeight)) {
                        edgeX = centerX + (dx > 0 ? halfWidth : -halfWidth);
                        edgeY = centerY + dy * halfWidth / Math.abs(dx);
                    } else {
                        edgeX = centerX + dx * halfHeight / Math.abs(dy);
                        edgeY = centerY + (dy > 0 ? halfHeight : -halfHeight);
                    }
                    break;
                    
                case 'decision':
                    // 菱形 - 使用更精确的几何计算
                    const diamondWidth = rect.width / 2 - 5;
                    const diamondHeight = rect.height / 2 - 5;
                    
                    // 处理零向量情况
                    if (dx === 0 && dy === 0) {
                        edgeX = centerX;
                        edgeY = centerY;
                        break;
                    }
                    
                    // 菱形的四个顶点
                    const topPoint = { x: centerX, y: centerY - diamondHeight };
                    const rightPoint = { x: centerX + diamondWidth, y: centerY };
                    const bottomPoint = { x: centerX, y: centerY + diamondHeight };
                    const leftPoint = { x: centerX - diamondWidth, y: centerY };
                    
                    // 计算方向与四个边的交点
                    let minDistance = Infinity;
                    let closestPoint = { x: centerX, y: centerY };
                    
                    // 检查与上边的交点
                    const topIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        topPoint.x, topPoint.y, rightPoint.x, rightPoint.y
                    );
                    if (topIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(topIntersection.x - centerX, 2) + 
                            Math.pow(topIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = topIntersection;
                        }
                    }
                    
                    // 检查与右边的交点
                    const rightIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        rightPoint.x, rightPoint.y, bottomPoint.x, bottomPoint.y
                    );
                    if (rightIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(rightIntersection.x - centerX, 2) + 
                            Math.pow(rightIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = rightIntersection;
                        }
                    }
                    
                    // 检查与下边的交点
                    const bottomIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        bottomPoint.x, bottomPoint.y, leftPoint.x, leftPoint.y
                    );
                    if (bottomIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(bottomIntersection.x - centerX, 2) + 
                            Math.pow(bottomIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = bottomIntersection;
                        }
                    }
                    
                    // 检查与左边的交点
                    const leftIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        leftPoint.x, leftPoint.y, topPoint.x, topPoint.y
                    );
                    if (leftIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(leftIntersection.x - centerX, 2) + 
                            Math.pow(leftIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = leftIntersection;
                        }
                    }
                    
                    edgeX = closestPoint.x;
                    edgeY = closestPoint.y;
                    break;
                    
                case 'parallelogram':
                    // 平行四边形 - 使用更精确的几何计算
                    const parallelogramOffset = Math.min(rect.width / 3, 30);
                    const pWidth = rect.width / 2 - 5;
                    const pHeight = rect.height / 2 - 5;
                    
                    // 处理零向量情况
                    if (dx === 0 && dy === 0) {
                        edgeX = centerX;
                        edgeY = centerY;
                        break;
                    }
                    
                    // 平行四边形的四个顶点
                    const pTopLeft = { x: centerX - pWidth + parallelogramOffset, y: centerY - pHeight };
                    const pTopRight = { x: centerX + pWidth, y: centerY - pHeight };
                    const pBottomRight = { x: centerX + pWidth - parallelogramOffset, y: centerY + pHeight };
                    const pBottomLeft = { x: centerX - pWidth, y: centerY + pHeight };
                    
                    // 计算方向与四个边的交点
                    let pMinDistance = Infinity;
                    let pClosestPoint = { x: centerX, y: centerY };
                    
                    // 检查与上边的交点
                    const pTopIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pTopLeft.x, pTopLeft.y, pTopRight.x, pTopRight.y
                    );
                    if (pTopIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pTopIntersection.x - centerX, 2) + 
                            Math.pow(pTopIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pTopIntersection;
                        }
                    }
                    
                    // 检查与右边的交点
                    const pRightIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pTopRight.x, pTopRight.y, pBottomRight.x, pBottomRight.y
                    );
                    if (pRightIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pRightIntersection.x - centerX, 2) + 
                            Math.pow(pRightIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pRightIntersection;
                        }
                    }
                    
                    // 检查与下边的交点
                    const pBottomIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pBottomRight.x, pBottomRight.y, pBottomLeft.x, pBottomLeft.y
                    );
                    if (pBottomIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pBottomIntersection.x - centerX, 2) + 
                            Math.pow(pBottomIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pBottomIntersection;
                        }
                    }
                    
                    // 检查与左边的交点
                    const pLeftIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pBottomLeft.x, pBottomLeft.y, pTopLeft.x, pTopLeft.y
                    );
                    if (pLeftIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pLeftIntersection.x - centerX, 2) + 
                            Math.pow(pLeftIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pLeftIntersection;
                        }
                    }
                    
                    edgeX = pClosestPoint.x;
                    edgeY = pClosestPoint.y;
                    break;
            }
            
            return { x: edgeX, y: edgeY };
        }

        // 计算图形边缘的连接点 (用于导出)
        function getEdgePointForExport(element, targetX, targetY, canvasRect) {
            const rect = element.getBoundingClientRect();
            
            const centerX = rect.left + rect.width / 2 - canvasRect.left;
            const centerY = rect.top + rect.height / 2 - canvasRect.top;
            const type = element.dataset.type;
            
            // 计算方向向量
            const dx = targetX - centerX;
            const dy = targetY - centerY;
            
            let edgeX, edgeY;
            
            switch(type) {
                case 'start':
                case 'end':
                    // 椭圆形
                    const rx = rect.width / 2 - 5; // 减去边距
                    const ry = rect.height / 2 - 5;
                    const t = Math.atan2(dy * rx, dx * ry);
                    edgeX = centerX + rx * Math.cos(t);
                    edgeY = centerY + ry * Math.sin(t);
                    break;
                    
                case 'process':
                    // 矩形
                    const halfWidth = rect.width / 2 - 5;
                    const halfHeight = rect.height / 2 - 5;
                    
                    // 计算矩形边上的交点
                    if (Math.abs(dx / halfWidth) > Math.abs(dy / halfHeight)) {
                        edgeX = centerX + (dx > 0 ? halfWidth : -halfWidth);
                        edgeY = centerY + dy * halfWidth / Math.abs(dx);
                    } else {
                        edgeX = centerX + dx * halfHeight / Math.abs(dy);
                        edgeY = centerY + (dy > 0 ? halfHeight : -halfHeight);
                    }
                    break;
                    
                case 'decision':
                    // 菱形 - 使用更精确的几何计算
                    const diamondWidth = rect.width / 2 - 5;
                    const diamondHeight = rect.height / 2 - 5;
                    
                    // 处理零向量情况
                    if (dx === 0 && dy === 0) {
                        edgeX = centerX;
                        edgeY = centerY;
                        break;
                    }
                    
                    // 菱形的四个顶点
                    const topPoint = { x: centerX, y: centerY - diamondHeight };
                    const rightPoint = { x: centerX + diamondWidth, y: centerY };
                    const bottomPoint = { x: centerX, y: centerY + diamondHeight };
                    const leftPoint = { x: centerX - diamondWidth, y: centerY };
                    
                    // 计算方向与四个边的交点
                    let minDistance = Infinity;
                    let closestPoint = { x: centerX, y: centerY };
                    
                    // 检查与上边的交点
                    const topIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        topPoint.x, topPoint.y, rightPoint.x, rightPoint.y
                    );
                    if (topIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(topIntersection.x - centerX, 2) + 
                            Math.pow(topIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = topIntersection;
                        }
                    }
                    
                    // 检查与右边的交点
                    const rightIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        rightPoint.x, rightPoint.y, bottomPoint.x, bottomPoint.y
                    );
                    if (rightIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(rightIntersection.x - centerX, 2) + 
                            Math.pow(rightIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = rightIntersection;
                        }
                    }
                    
                    // 检查与下边的交点
                    const bottomIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        bottomPoint.x, bottomPoint.y, leftPoint.x, leftPoint.y
                    );
                    if (bottomIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(bottomIntersection.x - centerX, 2) + 
                            Math.pow(bottomIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = bottomIntersection;
                        }
                    }
                    
                    // 检查与左边的交点
                    const leftIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        leftPoint.x, leftPoint.y, topPoint.x, topPoint.y
                    );
                    if (leftIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(leftIntersection.x - centerX, 2) + 
                            Math.pow(leftIntersection.y - centerY, 2)
                        );
                        if (dist < minDistance) {
                            minDistance = dist;
                            closestPoint = leftIntersection;
                        }
                    }
                    
                    edgeX = closestPoint.x;
                    edgeY = closestPoint.y;
                    break;
                    
                case 'parallelogram':
                    // 平行四边形 - 使用更精确的几何计算
                    const parallelogramOffset = Math.min(rect.width / 3, 30);
                    const pWidth = rect.width / 2 - 5;
                    const pHeight = rect.height / 2 - 5;
                    
                    // 处理零向量情况
                    if (dx === 0 && dy === 0) {
                        edgeX = centerX;
                        edgeY = centerY;
                        break;
                    }
                    
                    // 平行四边形的四个顶点
                    const pTopLeft = { x: centerX - pWidth + parallelogramOffset, y: centerY - pHeight };
                    const pTopRight = { x: centerX + pWidth, y: centerY - pHeight };
                    const pBottomRight = { x: centerX + pWidth - parallelogramOffset, y: centerY + pHeight };
                    const pBottomLeft = { x: centerX - pWidth, y: centerY + pHeight };
                    
                    // 计算方向与四个边的交点
                    let pMinDistance = Infinity;
                    let pClosestPoint = { x: centerX, y: centerY };
                    
                    // 检查与上边的交点
                    const pTopIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pTopLeft.x, pTopLeft.y, pTopRight.x, pTopRight.y
                    );
                    if (pTopIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pTopIntersection.x - centerX, 2) + 
                            Math.pow(pTopIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pTopIntersection;
                        }
                    }
                    
                    // 检查与右边的交点
                    const pRightIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pTopRight.x, pTopRight.y, pBottomRight.x, pBottomRight.y
                    );
                    if (pRightIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pRightIntersection.x - centerX, 2) + 
                            Math.pow(pRightIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pRightIntersection;
                        }
                    }
                    
                    // 检查与下边的交点
                    const pBottomIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pBottomRight.x, pBottomRight.y, pBottomLeft.x, pBottomLeft.y
                    );
                    if (pBottomIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pBottomIntersection.x - centerX, 2) + 
                            Math.pow(pBottomIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pBottomIntersection;
                        }
                    }
                    
                    // 检查与左边的交点
                    const pLeftIntersection = getLineIntersection(
                        centerX, centerY, targetX, targetY,
                        pBottomLeft.x, pBottomLeft.y, pTopLeft.x, pTopLeft.y
                    );
                    if (pLeftIntersection) {
                        const dist = Math.sqrt(
                            Math.pow(pLeftIntersection.x - centerX, 2) + 
                            Math.pow(pLeftIntersection.y - centerY, 2)
                        );
                        if (dist < pMinDistance) {
                            pMinDistance = dist;
                            pClosestPoint = pLeftIntersection;
                        }
                    }
                    
                    edgeX = pClosestPoint.x;
                    edgeY = pClosestPoint.y;
                    break;
            }
            
            return { x: edgeX, y: edgeY };
        }

        // 计算两条线段的交点
        function getLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4) {
            const denominator = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
            if (denominator === 0) {
                return null;
            }
            
            const t = (((x1 - x3) * (y3 - y4)) - ((y1 - y3) * (x3 - x4))) / denominator;
            const u = -(((x1 - x2) * (y1 - y3)) - ((y1 - y2) * (x1 - x3))) / denominator;
            
            if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
                const intersectionX = x1 + (t * (x2 - x1));
                const intersectionY = y1 + (t * (y2 - y1));
                return { x: intersectionX, y: intersectionY };
            }
            
            return null;
        }

        // 创建连线
        function createConnection(element1, element2) {
            const line = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            line.classList.add('connection-line');
            
            // 创建箭头标记
            const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
            const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
            const markerId = 'arrowhead-' + Date.now();
            marker.setAttribute('id', markerId);
            marker.setAttribute('markerWidth', '10');
            marker.setAttribute('markerHeight', '10');
            marker.setAttribute('refX', '9');
            marker.setAttribute('refY', '3');
            marker.setAttribute('orient', 'auto');
            
            const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
            polygon.setAttribute('points', '0 0, 10 3, 0 6');
            polygon.setAttribute('fill', '#666');
            
            marker.appendChild(polygon);
            defs.appendChild(marker);
            line.appendChild(defs);
            
            // 创建路径
            const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path.setAttribute('stroke', '#666');
            path.setAttribute('stroke-width', '2');
            path.setAttribute('fill', 'none');
            path.setAttribute('marker-end', 'url(#' + markerId + ')');
            
            line.appendChild(path);
            
            // 添加点击事件 - 单击选中
            line.addEventListener('click', (e) => {
                e.stopPropagation();
                selectConnection(line);
            });
            
            // 添加双击事件 - 双击添加文字
            line.addEventListener('dblclick', (e) => {
                e.stopPropagation();
                addConnectionText(line);
            });
            
            // 添加右键菜单事件
            line.addEventListener('contextmenu', (e) => {
                e.preventDefault();
                showConnectionContextMenu(e, line);
            });
            
            document.getElementById('canvas').appendChild(line);
            
            const connection = {
                line: line,
                path: path,
                textElement: null,
                element1: element1,
                element2: element2,
                controlPoint: null, // 添加控制点属性
                startPoint: null,   // 可移动的起点
                endPoint: null      // 可移动的终点
            };
            
            // 添加控制点和端点拖拽功能
            let isDragging = false;
            let dragType = null; // 'controlPoint', 'startPoint', 'endPoint'
            let dragOffsetX = 0;
            let dragOffsetY = 0;
            
            line.addEventListener('mousedown', (e) => {
                if (!connection.controlPoint && !connection.startPoint && !connection.endPoint) return;
                
                // 检查是否点击在控制点、起点或终点附近
                const point = line.createSVGPoint();
                point.x = e.clientX;
                point.y = e.clientY;
                const cursorPoint = point.matrixTransform(line.getScreenCTM().inverse());
                
                // 检查控制点
                if (connection.controlPoint) {
                    const distance = Math.sqrt(
                        Math.pow(cursorPoint.x - connection.controlPoint.x, 2) +
                        Math.pow(cursorPoint.y - connection.controlPoint.y, 2)
                    );
                    
                    if (distance < 10) {
                        isDragging = true;
                        dragType = 'controlPoint';
                        dragOffsetX = cursorPoint.x - connection.controlPoint.x;
                        dragOffsetY = cursorPoint.y - connection.controlPoint.y;
                        e.stopPropagation();
                        return;
                    }
                }
                
                // 检查起点
                if (connection.startPoint) {
                    const distance = Math.sqrt(
                        Math.pow(cursorPoint.x - connection.startPoint.x, 2) +
                        Math.pow(cursorPoint.y - connection.startPoint.y, 2)
                    );
                    
                    if (distance < 10) {
                        isDragging = true;
                        dragType = 'startPoint';
                        dragOffsetX = cursorPoint.x - connection.startPoint.x;
                        dragOffsetY = cursorPoint.y - connection.startPoint.y;
                        e.stopPropagation();
                        return;
                    }
                }
                
                // 检查终点
                if (connection.endPoint) {
                    const distance = Math.sqrt(
                        Math.pow(cursorPoint.x - connection.endPoint.x, 2) +
                        Math.pow(cursorPoint.y - connection.endPoint.y, 2)
                    );
                    
                    if (distance < 10) {
                        isDragging = true;
                        dragType = 'endPoint';
                        dragOffsetX = cursorPoint.x - connection.endPoint.x;
                        dragOffsetY = cursorPoint.y - connection.endPoint.y;
                        e.stopPropagation();
                        return;
                    }
                }
            });
            
            line.addEventListener('mousemove', (e) => {
                if (!isDragging || (!connection.controlPoint && !connection.startPoint && !connection.endPoint)) return;
                
                const point = line.createSVGPoint();
                point.x = e.clientX;
                point.y = e.clientY;
                const cursorPoint = point.matrixTransform(line.getScreenCTM().inverse());
                
                switch (dragType) {
                    case 'controlPoint':
                        if (connection.controlPoint) {
                            connection.controlPoint.x = cursorPoint.x - dragOffsetX;
                            connection.controlPoint.y = cursorPoint.y - dragOffsetY;
                        }
                        break;
                    case 'startPoint':
                        if (connection.startPoint) {
                            connection.startPoint.x = cursorPoint.x - dragOffsetX;
                            connection.startPoint.y = cursorPoint.y - dragOffsetY;
                        }
                        break;
                    case 'endPoint':
                        if (connection.endPoint) {
                            connection.endPoint.x = cursorPoint.x - dragOffsetX;
                            connection.endPoint.y = cursorPoint.y - dragOffsetY;
                        }
                        break;
                }
                
                updateConnections();
                e.stopPropagation();
            });
            
            line.addEventListener('mouseup', (e) => {
                isDragging = false;
                dragType = null;
            });
            
            line.addEventListener('mouseleave', (e) => {
                isDragging = false;
                dragType = null;
            });
            
            connections.push(connection);
            
            updateConnections();
            showToast('🔗 连线成功！');
        }

        // 添加连线文字
        function addConnectionText(line) {
            const connection = connections.find(conn => conn.line === line);
            if (!connection) return;
            
            // 如果已经有文字，直接编辑
            if (connection.textElement) {
                editConnectionText(connection.textElement);
                return;
            }
            
            // 计算连线路径的中间点
            const pathData = connection.path.getAttribute('d');
            const midPoint = getPathMidpoint(pathData);
            
            // 获取SVG元素的位置
            const svgRect = connection.line.getBoundingClientRect();
            const canvasRect = document.getElementById('canvas').getBoundingClientRect();
            
            // 计算绝对坐标
            const absoluteX = svgRect.left - canvasRect.left + midPoint.x;
            const absoluteY = svgRect.top - canvasRect.top + midPoint.y;
            
            // 创建文字元素
            const textElement = document.createElement('div');
            textElement.className = 'connection-text';
            textElement.contentEditable = true;
            textElement.style.left = absoluteX + 'px';
            textElement.style.top = absoluteY + 'px';
            textElement.textContent = '';
            
            // 添加到画布
            document.getElementById('canvas').appendChild(textElement);
            connection.textElement = textElement;
            
            // 添加事件监听
            textElement.addEventListener('click', (e) => {
                e.stopPropagation();
                selectConnection(line);
            });
            
            textElement.addEventListener('dblclick', (e) => {
                e.stopPropagation();
                editConnectionText(textElement);
            });
            
            // 立即进入编辑状态并聚焦
            editConnectionText(textElement);
        }

        // 计算SVG路径的中间点
        function getPathMidpoint(pathData) {
            // 解析路径数据
            const commands = pathData.match(/[MQL][^MQL]*/g);
            if (!commands || commands.length < 2) return { x: 0, y: 0 };
            
            let points = [];
            
            commands.forEach(cmd => {
                const type = cmd[0];
                const coords = cmd.slice(1).trim().split(/[\s,]+/).map(Number);
                
                if (type === 'M' && coords.length >= 2) {
                    points.push({ x: coords[0], y: coords[1] });
                } else if (type === 'Q' && coords.length >= 4) {
                    // 二次贝塞尔曲线，采样几个点
                    for (let t = 0; t <= 1; t += 0.2) {
                        const x = Math.pow(1-t, 2) * points[points.length-1].x + 
                                2 * (1-t) * t * coords[0] + 
                                Math.pow(t, 2) * coords[2];
                        const y = Math.pow(1-t, 2) * points[points.length-1].y + 
                                2 * (1-t) * t * coords[1] + 
                                Math.pow(t, 2) * coords[3];
                        points.push({ x, y });
                    }
                } else if (type === 'L' && coords.length >= 2) {
                    points.push({ x: coords[0], y: coords[1] });
                }
            });
            
            if (points.length === 0) return { x: 0, y: 0 };
            
            // 计算路径总长度
            let totalLength = 0;
            for (let i = 1; i < points.length; i++) {
                const dx = points[i].x - points[i-1].x;
                const dy = points[i].y - points[i-1].y;
                totalLength += Math.sqrt(dx * dx + dy * dy);
            }
            
            // 找到中间点
            const targetLength = totalLength / 2;
            let currentLength = 0;
            
            for (let i = 1; i < points.length; i++) {
                const dx = points[i].x - points[i-1].x;
                const dy = points[i].y - points[i-1].y;
                const segmentLength = Math.sqrt(dx * dx + dy * dy);
                
                if (currentLength + segmentLength >= targetLength) {
                    const ratio = (targetLength - currentLength) / segmentLength;
                    return {
                        x: points[i-1].x + dx * ratio,
                        y: points[i-1].y + dy * ratio
                    };
                }
                
                currentLength += segmentLength;
            }
            
            return points[points.length - 1];
        }

        // 编辑连线文字
        function editConnectionText(textElement) {
            textElement.contentEditable = true;
            textElement.classList.add('editing');
            textElement.focus();
            selectAllText(textElement);
            
            // 确保光标定位正确
            setTimeout(() => {
                textElement.focus();
                selectAllText(textElement);
            }, 0);
            
            // 编辑完成后移除编辑状态
            const finishEditing = () => {
                textElement.contentEditable = false;
                textElement.classList.remove('editing');
                
                // 如果文字为空，删除文字元素
                if (textElement.textContent.trim() === '') {
                    const connection = connections.find(conn => conn.textElement === textElement);
                    if (connection) {
                        textElement.remove();
                        connection.textElement = null;
                    }
                }
            };
            
            textElement.addEventListener('blur', finishEditing, { once: true });
            textElement.addEventListener('keydown', (e) => {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    textElement.blur();
                }
            });
        }

        // 选择连线
        function selectConnection(line) {
            clearSelection();
            line.classList.add('selected');
            selectedConnection = connections.find(conn => conn.line === line);
        }

        // 更新连线位置
        function updateConnections() {
            connections.forEach(conn => {
                const rect1 = conn.element1.getBoundingClientRect();
                const rect2 = conn.element2.getBoundingClientRect();
                const canvasRect = document.getElementById('canvas').getBoundingClientRect();
                
                let startPoint, endPoint;
                
                // 如果有可移动的起点和终点，则使用它们
                if (conn.startPoint && conn.endPoint) {
                    startPoint = conn.startPoint;
                    endPoint = conn.endPoint;
                } else {
                    // 否则计算边缘连接点
                    const centerX1 = rect1.left + rect1.width / 2 - canvasRect.left;
                    const centerY1 = rect1.top + rect1.height / 2 - canvasRect.top;
                    const centerX2 = rect2.left + rect2.width / 2 - canvasRect.left;
                    const centerY2 = rect2.top + rect2.height / 2 - canvasRect.top;
                    
                    startPoint = getEdgePoint(conn.element1, centerX2, centerY2);
                    endPoint = getEdgePoint(conn.element2, centerX1, centerY1);
                    
                    // 如果有可移动的点，更新它们
                    if (conn.startPoint) {
                        conn.startPoint.x = startPoint.x;
                        conn.startPoint.y = startPoint.y;
                    }
                    if (conn.endPoint) {
                        conn.endPoint.x = endPoint.x;
                        conn.endPoint.y = endPoint.y;
                    }
                }
                
                // 如果连接有控制点，则使用折线，否则使用直线
                let pathData;
                if (conn.controlPoint) {
                    // 使用折线（三段线）
                    const controlX = conn.controlPoint.x;
                    const controlY = conn.controlPoint.y;
                    
                    pathData = `M ${startPoint.x} ${startPoint.y} L ${controlX} ${controlY} L ${endPoint.x} ${endPoint.y}`;
                } else {
                    // 使用直线
                    pathData = `M ${startPoint.x} ${startPoint.y} L ${endPoint.x} ${endPoint.y}`;
                }
                
                // 计算连线的边界
                let minX = Math.min(startPoint.x, endPoint.x);
                let minY = Math.min(startPoint.y, endPoint.y);
                let maxX = Math.max(startPoint.x, endPoint.x);
                let maxY = Math.max(startPoint.y, endPoint.y);
                
                // 如果有控制点，也要考虑控制点
                if (conn.controlPoint) {
                    minX = Math.min(minX, conn.controlPoint.x);
                    minY = Math.min(minY, conn.controlPoint.y);
                    maxX = Math.max(maxX, conn.controlPoint.x);
                    maxY = Math.max(maxY, conn.controlPoint.y);
                }
                
                // 设置SVG的位置和大小（增加边距）
                const margin = 20;
                conn.line.style.left = (minX - margin) + 'px';
                conn.line.style.top = (minY - margin) + 'px';
                conn.line.style.width = (maxX - minX + 2 * margin) + 'px';
                conn.line.style.height = (maxY - minY + 2 * margin) + 'px';
                
                // 计算相对坐标
                const relStartX = startPoint.x - minX + margin;
                const relStartY = startPoint.y - minY + margin;
                const relEndX = endPoint.x - minX + margin;
                const relEndY = endPoint.y - minY + margin;
                
                if (conn.controlPoint) {
                    // 折线路径
                    const relControlX = conn.controlPoint.x - minX + margin;
                    const relControlY = conn.controlPoint.y - minY + margin;
                    pathData = `M ${relStartX} ${relStartY} L ${relControlX} ${relControlY} L ${relEndX} ${relEndY}`;
                } else {
                    // 直线路径
                    pathData = `M ${relStartX} ${relStartY} L ${relEndX} ${relEndY}`;
                }
                
                conn.path.setAttribute('d', pathData);
                
                // 添加或更新控制点、起点和终点的可视化标记
                // 清除现有的标记
                const existingMarkers = conn.line.querySelectorAll('.control-point, .endpoint-point');
                existingMarkers.forEach(marker => marker.remove());
                
                // 如果有可移动的控制点、起点和终点，则添加可视化标记
                if (conn.controlPoint || conn.startPoint || conn.endPoint) {
                    // 添加起点标记
                    if (conn.startPoint) {
                        const startCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                        startCircle.setAttribute('cx', relStartX);
                        startCircle.setAttribute('cy', relStartY);
                        startCircle.setAttribute('r', '6');
                        startCircle.classList.add('endpoint-point');
                        conn.line.appendChild(startCircle);
                    }
                    
                    // 添加终点标记
                    if (conn.endPoint) {
                        const endCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                        endCircle.setAttribute('cx', relEndX);
                        endCircle.setAttribute('cy', relEndY);
                        endCircle.setAttribute('r', '6');
                        endCircle.classList.add('endpoint-point');
                        conn.line.appendChild(endCircle);
                    }
                    
                    // 添加控制点标记
                    if (conn.controlPoint) {
                        const controlCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
                        const relControlX = conn.controlPoint.x - minX + margin;
                        const relControlY = conn.controlPoint.y - minY + margin;
                        controlCircle.setAttribute('cx', relControlX);
                        controlCircle.setAttribute('cy', relControlY);
                        controlCircle.setAttribute('r', '6');
                        controlCircle.classList.add('control-point');
                        conn.line.appendChild(controlCircle);
                    }
                }
                
                // 更新文字位置 - 如果有文字元素
                if (conn.textElement) {
                    const midPoint = getPathMidpoint(pathData);
                    const svgRect = conn.line.getBoundingClientRect();
                    const absoluteX = svgRect.left - canvasRect.left + midPoint.x;
                    const absoluteY = svgRect.top - canvasRect.top + midPoint.y;
                    
                    conn.textElement.style.left = absoluteX + 'px';
                    conn.textElement.style.top = absoluteY + 'px';
                }
            });
        }

        // 显示连线右键菜单
        function showConnectionContextMenu(e, line) {
            e.stopPropagation();
            
            // 隐藏其他菜单
            hideContextMenu();
            
            // 创建菜单
            const contextMenu = document.createElement('div');
            contextMenu.className = 'context-menu';
            contextMenu.style.position = 'absolute';
            contextMenu.style.left = e.clientX + 'px';
            contextMenu.style.top = e.clientY + 'px';
            contextMenu.style.zIndex = '1000';
            contextMenu.style.backgroundColor = 'white';
            contextMenu.style.border = '1px solid #ccc';
            contextMenu.style.borderRadius = '4px';
            contextMenu.style.padding = '4px 0';
            contextMenu.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
            
            const connection = connections.find(conn => conn.line === line);
            if (!connection) return;
            
            // 添加控制点选项
            if (!connection.controlPoint) {
                const addControlPointItem = document.createElement('div');
                addControlPointItem.className = 'context-menu-item';
                addControlPointItem.textContent = '添加控制点';
                addControlPointItem.style.padding = '8px 16px';
                addControlPointItem.style.cursor = 'pointer';
                addControlPointItem.addEventListener('mouseenter', () => {
                    addControlPointItem.style.backgroundColor = '#f0f0f0';
                });
                addControlPointItem.addEventListener('mouseleave', () => {
                    addControlPointItem.style.backgroundColor = 'white';
                });
                addControlPointItem.addEventListener('click', () => {
                    // 计算连线中点作为控制点
                    const rect1 = connection.element1.getBoundingClientRect();
                    const rect2 = connection.element2.getBoundingClientRect();
                    const canvasRect = document.getElementById('canvas').getBoundingClientRect();
                    
                    const centerX1 = rect1.left + rect1.width / 2 - canvasRect.left;
                    const centerY1 = rect1.top + rect1.height / 2 - canvasRect.top;
                    const centerX2 = rect2.left + rect2.width / 2 - canvasRect.left;
                    const centerY2 = rect2.top + rect2.height / 2 - canvasRect.top;
                    
                    const startPoint = getEdgePoint(connection.element1, centerX2, centerY2);
                    const endPoint = getEdgePoint(connection.element2, centerX1, centerY1);
                    
                    // 设置控制点为连线中点偏移一定距离
                    connection.controlPoint = {
                        x: (startPoint.x + endPoint.x) / 2,
                        y: (startPoint.y + endPoint.y) / 2 - 30
                    };
                    
                    // 启用起点和终点的移动功能
                    connection.startPoint = { x: startPoint.x, y: startPoint.y };
                    connection.endPoint = { x: endPoint.x, y: endPoint.y };
                    
                    updateConnections();
                    hideContextMenu();
                });
                contextMenu.appendChild(addControlPointItem);
            } else {
                const removeControlPointItem = document.createElement('div');
                removeControlPointItem.className = 'context-menu-item';
                removeControlPointItem.textContent = '移除控制点';
                removeControlPointItem.style.padding = '8px 16px';
                removeControlPointItem.style.cursor = 'pointer';
                removeControlPointItem.addEventListener('mouseenter', () => {
                    removeControlPointItem.style.backgroundColor = '#f0f0f0';
                });
                removeControlPointItem.addEventListener('mouseleave', () => {
                    removeControlPointItem.style.backgroundColor = 'white';
                });
                removeControlPointItem.addEventListener('click', () => {
                    connection.controlPoint = null;
                    connection.startPoint = null;
                    connection.endPoint = null;
                    updateConnections();
                    hideContextMenu();
                });
                contextMenu.appendChild(removeControlPointItem);
            }
            
            document.body.appendChild(contextMenu);
            
            // 点击其他地方隐藏菜单
            const hideMenuHandler = () => {
                hideContextMenu();
                document.removeEventListener('click', hideMenuHandler);
            };
            setTimeout(() => {
                document.addEventListener('click', hideMenuHandler);
            }, 0);
        }
        
        // 隐藏右键菜单
        function hideContextMenu() {
            const menus = document.querySelectorAll('.context-menu');
            menus.forEach(menu => menu.remove());
        }

        // 颜色选择器
        function initColorPicker() {
            const colorOptions = document.querySelectorAll('.color-option');
            colorOptions.forEach(option => {
                option.addEventListener('click', () => {
                    colorOptions.forEach(opt => opt.classList.remove('selected'));
                    option.classList.add('selected');
                    selectedColor = option.dataset.color;
                    
                    if (selectedElement) {
                        selectedElement.dataset.color = selectedColor;
                        const svg = selectedElement.querySelector('svg');
                        const shape = svg.querySelector('ellipse, rect, path');
                        if (shape) {
                            shape.setAttribute('fill', selectedColor);
                        }
                        showToast('🎨 颜色已更改！');
                    }
                });
            });
        }

        // 键盘快捷键
        function initKeyboardShortcuts() {
            document.addEventListener('keydown', (e) => {
                if (e.key === 'Delete') {
                    if (selectedElement) {
                        deleteElement(selectedElement);
                    } else if (selectedConnection) {
                        deleteConnection(selectedConnection);
                    }
                } else if (e.key === 'Escape') {
                    if (connectingElement) {
                        cancelConnectionMode();
                    }
                    if (isConnecting) {
                        firstElement.classList.remove('selected');
                        isConnecting = false;
                        firstElement = null;
                        showToast('❌ 已取消连线');
                    }
                }
            });
        }

        // 删除元素
        function deleteElement(element) {
            // 删除相关连线
            connections = connections.filter(conn => {
                if (conn.element1 === element || conn.element2 === element) {
                    conn.line.remove();
                    if (conn.textElement) {
                        conn.textElement.remove();
                    }
                    return false;
                }
                return true;
            });
            
            element.remove();
            elements = elements.filter(el => el !== element);
            selectedElement = null;
            showToast('🗑️ 图形已删除');
        }

        // 删除连线
        function deleteConnection(connection) {
            connection.line.remove();
            if (connection.textElement) {
                connection.textElement.remove();
            }
            connections = connections.filter(conn => conn !== connection);
            selectedConnection = null;
            showToast('🗑️ 连线已删除');
        }

        // 加载模板
        function loadTemplate(templateName) {
            clearCanvas();
            
            switch(templateName) {
                case 'morning':
                    createShape('start', 300, 50);
                    createShape('process', 280, 150);
                    createShape('process', 280, 250);
                    createShape('process', 280, 350);
                    createShape('end', 300, 450);
                    
                    // 设置文字
                    setTimeout(() => {
                        elements[0].querySelector('.element-content').textContent = '起床';
                        elements[1].querySelector('.element-content').textContent = '刷牙洗脸';
                        elements[2].querySelector('.element-content').textContent = '吃早餐';
                        elements[3].querySelector('.element-content').textContent = '上学';
                        elements[4].querySelector('.element-content').textContent = '到校';
                        
                        // 创建连线
                        for (let i = 0; i < elements.length - 1; i++) {
                            createConnection(elements[i], elements[i + 1]);
                        }
                    }, 100);
                    break;
                    
                case 'homework':
                    createShape('start', 300, 50);
                    createShape('process', 280, 150);
                    createShape('decision', 300, 250);
                    createShape('process', 180, 350);
                    createShape('process', 380, 350);
                    createShape('end', 300, 450);
                    
                    setTimeout(() => {
                        elements[0].querySelector('.element-content').textContent = '开始写作业';
                        elements[1].querySelector('.element-content').textContent = '拿出作业本';
                        elements[2].querySelector('.element-content').textContent = '都会做吗？';
                        elements[3].querySelector('.element-content').textContent = '请教老师';
                        elements[4].querySelector('.element-content').textContent = '完成作业';
                        elements[5].querySelector('.element-content').textContent = '结束';
                        
                        createConnection(elements[0], elements[1]);
                        createConnection(elements[1], elements[2]);
                        createConnection(elements[2], elements[3]);
                        createConnection(elements[2], elements[4]);
                        createConnection(elements[3], elements[5]);
                        createConnection(elements[4], elements[5]);
                    }, 100);
                    break;
                    
                case 'game':
                    createShape('start', 300, 50);
                    createShape('process', 280, 150);
                    createShape('decision', 300, 250);
                    createShape('process', 180, 350);
                    createShape('process', 380, 350);
                    createShape('decision', 300, 450);
                    createShape('end', 300, 550);
                    
                    setTimeout(() => {
                        elements[0].querySelector('.element-content').textContent = '开始游戏';
                        elements[1].querySelector('.element-content').textContent = '选择角色';
                        elements[2].querySelector('.element-content').textContent = '生命值>0？';
                        elements[3].querySelector('.element-content').textContent = '游戏结束';
                        elements[4].querySelector('.element-content').textContent = '继续冒险';
                        elements[5].querySelector('.element-content').textContent = '通关了吗？';
                        elements[6].querySelector('.element-content').textContent = '恭喜通关';
                        
                        createConnection(elements[0], elements[1]);
                        createConnection(elements[1], elements[2]);
                        createConnection(elements[2], elements[3]);
                        createConnection(elements[2], elements[4]);
                        createConnection(elements[4], elements[5]);
                        createConnection(elements[5], elements[6]);
                        createConnection(elements[5], elements[2]);
                    }, 100);
                    break;
            }
            
            showToast('📚 模板已加载！');
        }

        // 清空画布（内部使用）
        function clearCanvas() {
            const canvas = document.getElementById('canvas');
            canvas.innerHTML = '';
            
            elements = [];
            connections = [];
            elementIdCounter = 0;
            selectedElement = null;
            selectedConnection = null;
            isConnecting = false;
            firstElement = null;
            connectingElement = null;
            hideConnectionModeIndicator();
        }

        // 从本地加载
        function loadFromLocal() {
            const data = localStorage.getItem('flowchartData');
            if (data) {
                const parsed = JSON.parse(data);
                // 这里可以实现加载逻辑
            }
        }

        // 下载图片
        function downloadImage() {
            const canvas = document.getElementById('exportCanvas');
            if (!canvas || canvas.width === 0 || canvas.height === 0) {
                showToast('❌ 导出失败，请稍后重试');
                return;
            }
            
            const link = document.createElement('a');
            link.download = '我的流程图.png';
            link.href = canvas.toDataURL('image/png');
            link.click();
            showToast('📸 图片已下载！');
            closeModal();
        }

        // 关闭模态框
        function closeModal() {
            const modal = document.getElementById('exportModal');
            if (modal) {
                modal.classList.remove('show');
            }
        }

        // 显示帮助
        function toggleHelp() {
            const helpPanel = document.getElementById('helpPanel');
            helpPanel.classList.toggle('show');
        }

        // 显示提示
        function showToast(message) {
            const toast = document.getElementById('toast');
            toast.textContent = message;
            toast.classList.add('show');
            
            setTimeout(() => {
                toast.classList.remove('show');
            }, 3000);
        }

        // 选中所有文字
        function selectAllText(element) {
            const range = document.createRange();
            range.selectNodeContents(element);
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
        }

        // 窗口大小改变时更新连线
        window.addEventListener('resize', updateConnections);
    </script>
</body>
</html>